#include <stdlib.h>
#include "readpng.h"

png_structp png_ptr;
png_infop info_ptr;
u32 pngucursor = 0;
const png_byte* pngubuffer = NULL;
png_bytep * row_pointers;
int width, height;
png_byte color_type;
png_byte bit_depth;

static void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length)
{
	memcpy (data, pngubuffer+pngucursor, length);
	pngucursor += length;
}

png_infop read_png_file(const png_byte* buffer)
{
	if(png_sig_cmp((png_byte*)buffer, 0, 8))
		return NULL;

	/* initialize stuff */
	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	
	if (!png_ptr)
		return NULL;

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
	{
//png_bytep * row_pointers;
	        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return NULL;
	}

	if (setjmp(png_jmpbuf(png_ptr)))
	{
	        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		// info_ptr?
		return NULL;
	}

//	png_init_io(png_ptr, fp);

	pngucursor = 0;
	pngubuffer = buffer;
	png_set_read_fn (png_ptr, NULL, pngu_read_data_from_buffer);
//	png_set_sig_bytes(png_ptr, 8);

	png_read_info(png_ptr, info_ptr);

	width = info_ptr->width;
	height = info_ptr->height;
	color_type = info_ptr->color_type;
	bit_depth = info_ptr->bit_depth;

//	number_of_passes = png_set_interlace_handling(png_ptr);
	png_set_interlace_handling(png_ptr);
	png_read_update_info(png_ptr, info_ptr);

	/* read file */
	if (setjmp(png_jmpbuf(png_ptr)))
		return NULL;
//		abort_("[read_png_file] Error during read_image");

	row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
	int y;
	for (y=0; y<height; y++)
		row_pointers[y] = (png_byte*) malloc(info_ptr->rowbytes);

	png_read_image(png_ptr, row_pointers);
	return info_ptr;
}

bool png2tex(u8 *output)
{
	char AR[32];
	char GB[32];
	if (info_ptr->color_type != PNG_COLOR_TYPE_RGBA)
		return false;
	if(((height%4)!=0)||((width%4)!=0))
		return false;

	int y;
	for (y=0; y<height; y+=4) {
//	for (y=0; y<64; y+=4) {
		png_byte* row1 = row_pointers[y+0];
		png_byte* row2 = row_pointers[y+1];
		png_byte* row3 = row_pointers[y+2];
		png_byte* row4 = row_pointers[y+3];
		
		int x;
		for (x=0; x<width; x+=4)
      {
	int i;
        for (i=0;i<4;i++) {
			png_byte* ptr1 = &(row1[(x+i)*4]);
			png_byte* ptr2 = &(row2[(x+i)*4]);
			png_byte* ptr3 = &(row3[(x+i)*4]);
			png_byte* ptr4 = &(row4[(x+i)*4]);

            AR[(i*2)+ 0]=ptr1[3];AR[(i*2)+ 1]=ptr1[0];
          AR[(i*2)+ 8]=ptr2[3];AR[(i*2)+ 9]=ptr2[0];
            AR[(i*2)+16]=ptr3[3];AR[(i*2)+17]=ptr3[0];
            AR[(i*2)+24]=ptr4[3];AR[(i*2)+25]=ptr4[0];

            GB[(i*2)+ 0]=ptr1[1];GB[(i*2)+ 1]=ptr1[2];
            GB[(i*2)+ 8]=ptr2[1];GB[(i*2)+ 9]=ptr2[2];
           GB[(i*2)+16]=ptr3[1];GB[(i*2)+17]=ptr3[2];
            GB[(i*2)+24]=ptr4[1];GB[(i*2)+25]=ptr4[2];
		}
	memcpy(output, AR, sizeof(AR));
	output+=sizeof(AR);
	memcpy(output, GB, sizeof(GB));
	output+=sizeof(GB);
//		fwrite(AR, sizeof(AR[0]), sizeof(AR)/sizeof(AR[0]), fp);
//    	fwrite(GB, sizeof(GB[0]), sizeof(GB)/sizeof(GB[0]), fp);
     }
	}
//	fclose(fp);
//    printf("done\n");
	return true;
}
